package com.wxsong.authplatform.authweb.controller.authority;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.wxsong.authplatform.authweb.util.Base64Util;
import com.wxsong.authplatform.authweb.util.ListResponse;
import com.wxsong.authplatform.authweb.util.Response;
import com.wxsong.authplatform.authweb.util.ResponseCode;
import com.wxsong.authplatform.authweb.controller.BaseController;
import com.wxsong.authplatform.authweb.controller.authority.dto.AuthorityDTO;
import com.wxsong.authplatform.authweb.exception.InstantException;
import com.wxsong.authplatform.authweb.model.authority.Authority;
import com.wxsong.authplatform.authweb.service.authority.AuthorityService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/authority")
public class AuthorityController extends BaseController {

    private Logger logger = LoggerFactory.getLogger(AuthorityController.class);

    @Resource
    private AuthorityService authorityService;

    @RequestMapping(value = "/index")
    public String index(){
        return "authority/index";
    }

    @RequestMapping(value = "/add_index")
    public String toAdd(){
        return "authority/add";
    }

    @RequestMapping(value = "/update_index")
    public String toUpdate(ModelMap modelMap, String ids){
        String id = Base64Util.decode(ids);
        Authority authority = authorityService.getById(Long.parseLong(id));
        modelMap.put("authority", authority);
        modelMap.put("id", Base64Util.encode(authority.getId()+""));
        return "authority/update";
    }

    @RequestMapping(value = "/list", method = RequestMethod.POST)
    @ResponseBody
    public Response list(AuthorityDTO authorityDTO){
        System.out.println(authorityDTO);
        Map<String, Object> paramMap = Maps.newHashMap();
        List list = Lists.newArrayList();
        try {
            paramMap.put("name", authorityDTO.getName());
            Long count = authorityService.count(paramMap);
            if (count.compareTo(0l) > 0) {
                list = authorityService.list(getFrom(authorityDTO.getPage(), getSize(authorityDTO.getRows())), getSize(authorityDTO.getRows()), paramMap);
            }
            parseList(list);
            return ListResponse.success(count, list);
        }catch (Exception e){
            logger.error("/authority/list  error", e);
            return Response.fail(ResponseCode.FAIL.info);
        }

    }

    private void parseList(List<Authority> list) {
        List tmp = Lists.newArrayList();
        for (Authority authority : list){
            AuthorityDTO authorityDTO = new AuthorityDTO();
            authorityDTO.setId(Base64Util.encode(authority.getId()+""));
            authorityDTO.setName(authority.getName());
            tmp.add(authorityDTO);
        }
        list.clear();
        list.addAll(tmp);
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @ResponseBody
    public Response add(AuthorityDTO authorityDTO){
        Map resultMap = Maps.newHashMap();
        Authority authority = changeAuthority(authorityDTO);
        try {
            check(authority);
            int i = authorityService.add(authority);
            if(i < 1){
                return Response.fail(ResponseCode.ADD_AUTHORITY_FAIL);
            }
        }catch (InstantException e){
            logger.error("/authority/add  error", e);
            return Response.fail(ResponseCode.ADD_AUTHORITY_FAIL.code, e.getMessage());
        }catch (Exception e){
            logger.error("/authority/add  error", e);
            return Response.fail(ResponseCode.ADD_AUTHORITY_FAIL);
        }
        return Response.success(resultMap);
    }

    @RequestMapping(value = "/modify", method = RequestMethod.POST)
    @ResponseBody
    public Response modify(AuthorityDTO authorityDTO){
        Map resultMap = Maps.newHashMap();
        try {
            Long id = Long.parseLong(Base64Util.decode(authorityDTO.getId()));
            Authority authority = authorityService.getById(id);
            if(null == authority){
                throw new InstantException("权限不存在");
            }
            int c = authorityService.updateInfo(id, authorityDTO.getName());
            if (c < 0) {
                return Response.fail(ResponseCode.UPDATE_AUTHORITY_FAIL);
            }
        }catch (InstantException e){
            logger.error("/authority/modify  error", e);
            return Response.fail(ResponseCode.UPDATE_AUTHORITY_FAIL.code, e.getMessage());
        }catch (Exception e){
            logger.error("/authority/modify  error", e);
            return Response.fail(ResponseCode.UPDATE_AUTHORITY_FAIL);
        }
        return Response.success(resultMap);
    }
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ResponseBody
    public Response delete(String idStr){
        Map resultMap = Maps.newHashMap();
        try {
            Long[] ids = decodeIds(idStr);
            int count = authorityService.delete(ids);
            if (count < 0) {
                return Response.fail(ResponseCode.DELETE_AUTHORITY_FAIL);
            }
        }catch (InstantException e){
            logger.error("/authority/delete  error", e);
            return Response.fail(ResponseCode.DELETE_AUTHORITY_FAIL.code, e.getMessage());
        }catch (Exception e){
            logger.error("/authority/delete  error", e);
            return Response.fail(ResponseCode.DELETE_AUTHORITY_FAIL.info);
        }
        return Response.success(resultMap);
    }

    @RequestMapping(value = "/menu_index")
    public String toAuth(ModelMap modelMap, String id) {
        id = Base64Util.decode(id);
        Long longId = Long.parseLong(id);
        Authority authority = authorityService.getById(longId);
//        Long[] ids = ids(authority.getMenus());
//        List<Menu> hasMenus = authorityService.hasMenus(ids);
//        List<Menu> noMenus = authorityService.noMenus(ids);
//        modelMap.put("has", hasMenus);
//        modelMap.put("no", noMenus);
//        modelMap.put("id", Base64Util.encode(authority.getId() + ""));
        return "authority/menu";
    }

    @RequestMapping(value = "/modifyMenus", method = RequestMethod.POST)
    @ResponseBody
    public Response modifyMenus(String ids, String authId){
        Map resultMap = Maps.newHashMap();
        try {
            Subject subject = SecurityUtils.getSubject();
//            Users users = (Users)subject.getSession().getAttribute(Const.SESSION_USER_KEY);//操作人
            Authority authority = authorityService.getById(Long.parseLong(Base64Util.decode(authId)));
            if(null == authority){
                throw new InstantException("被授权权限为空");
            }
            int count = authorityService.modifyMenus(ids, authority.getId());
            if (count < 0) {
                return Response.fail(ResponseCode.GRANT_AUTH_MENU_FAIL);
            }
        }catch (InstantException e){
            logger.error("/authority/modifyMenu  error", e);
            return Response.fail(ResponseCode.GRANT_AUTH_MENU_FAIL.code, e.getMessage());
        }catch (Exception e){
            logger.error("/authority/modifyMenu  error", e);
            return Response.fail(ResponseCode.GRANT_AUTH_MENU_FAIL.info);
        }
        return Response.success(resultMap);
    }

    private boolean check(Authority authority) throws InstantException{
        if(StringUtils.isBlank(authority.getName())){
            throw new InstantException("参数不合法");
        }
        return true;
    }

    private Authority changeAuthority(AuthorityDTO authorityDTO) {
        String name = authorityDTO.getName();
        Authority authority = new Authority(name);
        return authority;
    }
}
